package com.nsharmon.dao.entity;

import java.util.List;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Transient;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.nsharmon.l18n.L18n;
import com.nsharmon.webapp.listeners.HibernateSessionListener;

@Entity
@DiscriminatorValue("equality")
public class EqualityAxiom extends Axiom { 
	public enum EqualityVariant {
		Default,
		IsCalledVariant
	}
	
	public EqualityAxiom() {
		setVariant(EqualityVariant.Default);
	}

	@Transient
	public String toString() {
		return toString(getVariant());
	}
	
	@Transient
	public String toString(Enum<?> variant) {
		List<EntityObject> entities = getEntities();
		String toString = null;
		if(entities.size() == 2) {
			toString = L18n.getMessage(getClass(), variant.toString(), entities.get(0), entities.get(1));
		} else {
			for(int i=0; i + 1 < entities.size(); i++) {
				if(i == 0) {
					toString = L18n.getMessage(getClass(), variant.toString(), entities.get(i), entities.get(i + 1));
				} else {
					toString += L18n.getMessage(getClass(), variant.toString(), toString, entities.get(i + 1));
				}
			}
		}
		return toString;
	}
	
	@Transient
	public static Axiom is(Project project, EqualityVariant variant, String entity1Name, String entity2Name, String ... params ) {
		return is(null, project, variant, entity1Name, entity2Name, params);
	}
	
	@Transient
	public static Axiom is(Session session, Project project, EqualityVariant variant, String entity1Name, String entity2Name, String ... params) {
		Axiom axiom = null;
		boolean localSession = false;
		Transaction trx = null;
		if(session == null) {
			localSession = true;
			session = HibernateSessionListener.openSession();
			trx = session.beginTransaction();
		}
		
		try {
			axiom = new EqualityAxiom();
			axiom.setProject(project);
			axiom.setVariant(variant);
			project.getAxioms().add(axiom);
			
			EntityObject entity1 = EntityObject.getOrCreate(session, entity1Name);
			axiom.getEntities().add(entity1);

			EntityObject entity2 = EntityObject.getOrCreate(session, entity2Name);
			axiom.getEntities().add(entity2);
			
			for(String param : params) {
				Parameter parameter = new Parameter(param);
				axiom.getParameters().add(parameter);
			}
			
			session.update(project);
			
			if(localSession) {
				trx.commit();
			}
		} catch(HibernateException e) {
			axiom = null;
			
			if(localSession) {
				trx.rollback();
			}
			throw e;
		} finally {
			if(localSession) {
				session.close();
			}
		}
		return axiom;		
	}
}
